package Day_0222.Spring;

/**
 * @author zxc
 * @date 2023/02/22 16:08
 **/
public class SpringBean {
    public static void main(String[] args) {
        /**
         * 谈一谈对于Spring Bean的理解
         * ===》
         * 一，Spring Bean的概念
         * （1）Spring beans 是那些形成Spring应用的主干的java对象。
         * （2）Spring Beans被Spring IOC容器初始化，装配，和管理。
         * （3）这些beans通过容器中配置的元数据创建。比如，以XML文件中 的形式定义。
         * （4）Spring Bean 的定义 ：包含容器必知的所有配置元数据，包括如何创建一个bean，它的生命周期详情及它的依赖关系等等。
         *
         * 二，给Spring 容器提供配置元数据的方式
         * （1）XML配置文件。
         * （2）基于注解的配置。
         * （3）基于java的配置。
         *
         * 三，Spring配置文件中所包含的信息
         * Spring配置文件是个XML 文件，这个文件包含了类信息，描述了如何配置它们，以及如何相互调用
         * ===》
         * 总结 ：
         * xml配置文件，包含了
         * （1）类的元数据信息;
         * （2）类的配置方法;
         * （3）类之间的依赖关系;
         *
         * 四，Spring基于xml文件，注入bean的方法
         * 1. Set方法注入;
         * 2. 构造器注入 ：
         * ①通过index设置参数的位置;
         * ②通过type设置参数类型;
         * 3. 静态工厂注入;
         * 4. 实例工厂;
         *
         * 五，解释Spring支持的几种bean的作用域
         * 1.Spring框架支持以下五种bean的作用域：
         * （1）singleton ：
         *  bean在每个Spring ioc 容器中只有一个实例。
         *
         * （2）prototype ：
         *  一个bean的定义可以有多个实例。
         *
         * （3）request ：
         *  每次http请求都会创建一个bean，该作用域仅在基于web的Spring ApplicationContext情形下有效。
         *
         * （4）session ：
         *  在一个HTTP Session中，一个bean定义对应一个实例。
         *  该作用域仅在基于web的SpringApplicationContext情形下有效。
         *
         * （5）global-session：
         *  在一个全局的HTTP Session中，一个bean定义对应一个实例。
         *  该作用域仅在基于web的Spring ApplicationContext情形下有效。
         *
         * 2.缺省（default）的Spring bean 的作用域是Singleton。
         * 使用 prototype 作用域需要慎重的思考，因为频繁创建和销毁 bean 会带来很大的性能开销。
         *
         * 六，Spring框架中的单例bean是线程安全的嘛
         * ===》
         * 不是，Spring框架中的单例bean不是线程安全的。
         * （1）spring 中的 bean 默认是单例模式，spring 框架并没有对单例 bean 进行多线程的封装处理。
         * （2）实际上，大部分时候 spring bean 无状态的（比如 dao 类），所有某种程度上来说 bean 也是安全的，
         * （3）如果 bean 有状态的话（比如 view model 对象），那就要开发者自己去保证线程安全了，
         *  最简单的就是改变 bean 的作用域，把“singleton”变更为“prototype”，这样请求 bean 相当于 new Bean()了，
         *  所以就可以保证线程安全了。
         * ===》
         * 即，在多线程情况下，若是bean处于singleton作用域的话，则代表了其只能够存在一个对象实例，
         * 多个线程对于该bean实例进行修改（等价于，对于同一个数据进行修改），导致出现 例如，线程a所修改的数据被线程b所修改的数据覆盖;
         *
         * 注意 ：
         * 1.有状态就是有数据存储功能。
         * 2.无状态就是不会保存数据。
         *
         * 七，Spring如何处理线程并发问题
         * （1）在一般情况下，只有无状态的Bean才可以在多线程环境下共享，
         *  在Spring中，绝大部分Bean都可以声明为singleton作用域，
         *  因为Spring对一些Bean中，非线程安全状态采用ThreadLocal进行处理，解决线程安全问题。
         *
         * （2）ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
         *
         * （3）同步机制采用了“时间换空间”的方式，仅提供一份变量，不同的线程在访问前需要获取锁，没获得锁的线程则需要排队。
         *
         * （4）ThreadLocal采用了“空间换时间”的方式。
         *  ThreadLocal会为每一个线程提供一个独立的变量副本，从而隔离了多个线程对数据的访问冲突。
         *  因为每一个线程都拥有自己的变量副本，从而也就没有必要对该变量进行同步了。
         *  ThreadLocal提供了线程安全的共享对象，在编写多线程代码时，可以把不安全的变量封装进ThreadLocal。
         *
         */
    }
}
